function ajaxCreateRequestObject()
{
	var xmlhttp = false;
	if (window.XMLHttpRequest) 
	{
		xmlhttp = new XMLHttpRequest();
	}
	else if (window.ActiveXObject)// code for IE
	{
		try {
			xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		} 
		catch (e) {
			try {
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (E) {
				xmlhttp=false;
			}
		}
	}
	return xmlhttp;
}

// Create global objects
if (typeof ajaxXmlHttp == 'undefined') {
	var ajaxXmlHttp = ajaxCreateRequestObject();
}
if (typeof ajaxQueue == 'undefined') {
	var ajaxQueue = new Array();
}

// Watchdog mechanism
var ajaxWatchdogPeriod = 5000;
function ajaxWatchdog()
{
	ajaxProcess();
	setTimeout("ajaxWatchdog()", ajaxWatchdogPeriod);
}
ajaxWatchdog();

function ajaxProcess()
{
	if (ajaxQueue.length == 0) return;
	if (!ajaxXmlHttp) return;

	// Check whether XmlHttpRequest object is free
	state = ajaxXmlHttp.readyState;
	if (state != 0 && state != 4) return;
	
	// Take task from queue
	var task = ajaxQueue[0];
	for (i = 0; i < ajaxQueue.length-1; i++) ajaxQueue[i] = ajaxQueue[i+1];
	ajaxQueue.length--;
    
	// Start task
	ajaxXmlHttp.open('get', task.url);
	ajaxXmlHttp.onreadystatechange = function() 
	{
		if (ajaxXmlHttp.readyState == 4)
		{
			if (ajaxXmlHttp.status == 200)
			{
				task.response = ajaxXmlHttp.responseText;
				task.callbackFunction(task);
				
				setTimeout("ajaxProcess()", 1);
			}
		}
	}
	ajaxXmlHttp.send(null);
}


function ajaxLoadData(url, callbackFunction, userData)
{
	var task = {
		'url':              url,
		'callbackFunction': callbackFunction,
        'response':         null,
        'userData':         userData
	};
    
	ajaxQueue.push(task);
	ajaxProcess();
}


function ajaxSubmitDataExt(url, onLoad, userData) {
	handler = function handlerFunction(task) {
        onLoad(task);
	}
	ajaxLoadData(ajaxMakeUrlUniq(url), handler, userData);
}

function ajaxLoadDataToInnerHtmlExt(url, objId, onLoad, userData) {
	handler = function handlerFunction(task) {
		document.getElementById(objId).innerHTML = task.response;
        onLoad(task);
	}
	ajaxLoadData(ajaxMakeUrlUniq(url), handler, userData);
}

function ajaxLoadDataToInnerHtml(url, objId) {
	handler = function handlerFunction(task) {
		document.getElementById(objId).innerHTML = task.response;
	}
	ajaxLoadData(ajaxMakeUrlUniq(url), handler);
}

function ajaxLoadDataToInnerHtmlContinuously(url, objId, delay)
{
	ajaxLoadDataToInnerHtml(url, objId);
	
	thisCall = 'ajaxLoadDataToInnerHtmlContinuously("'+url+'", "'+objId+'", '+delay+')';
	setTimeout(thisCall, delay);
}
   

function ajaxAppendToUrl(url, s0)
{
    var s = "";
    var i;

    for (i = 1; i < arguments.length; i++) {
        if (s.length) {
            s += '&';
        }
        s += arguments[i];
    }

	if (s == "") return url;
      
	if (url.indexOf('?') == -1) {
		url += "?";
	}
	else {
		url += "&";
	}
	return url + s;
}

function ajaxMakeUrlUniqParam()
{
	return 'temp=' + Math.random();
}

function ajaxMakeUrlUniq(url)
{
	return ajaxAppendToUrl(url, ajaxMakeUrlUniqParam());
}

function ajaxUrlEncodeData(str)
{
	// return escape(str);

	// TODO[SlavaK]: replce this function with code from following url for 
	// old browser compatibility: 
	// http://www.webtoolkit.info/javascript/utils/utf8-decode-encode/source/index.html
	return encodeURIComponent(str);
}

function ajaxUrlDecodeData(str)
{
	// replace "+" with " "
 	str = str.replace(/\+/g, " ");
	
	return  unescape(str);
}


function ajaxFormElementToUrl(el)
{
	// el :: type, name, value
	if (el.type == 'checkbox' && !el.checked) return "";
	if (el.type == 'radio' && !el.checked) return "";
	if (el.type == 'submit' || el.type == 'button') return "";

	return el.name + "=" + ajaxUrlEncodeData(el.value);
}

//ajaxFormDataToUrl
function ajaxFormToUrl(formName)
{
	var url = "";
	var theForm = document.getElementsByName(formName)[0];

	for (var i = 0; i < theForm.elements.length; i++)
	{
		var s = ajaxFormElementToUrl(theForm.elements[i])
		if (s == "") continue;

		if (url != "") url += "&";
		url += s;
	}
	
	return url;
}

function ajaxFormElementsToUrl(elements)
{
	var url = "";
	
	for (var i = 0; i < elements.length; i++)
	{
		var s = ajaxFormElementToUrl(elements[i])
		if (s == "") continue;
		
		if (url != "") url += "&";
		url += s;
	}
	
	return url;
}

function ajaxVarListToUrl(vl)
{
	var url = "";

	for (var i = 0; i < vl.length; i++)
	{
		var s = vl[i].n + "=" + ajaxUrlEncodeData(vl[i].v);
		
		if (url != "") url += "&";
		url += s;
	}
	
	return url;
}

